package webengine

// 扫描 应用目录下不需要鉴权的方法

import (
	"encoding/json"
	"go/ast"
	"go/parser"
	"go/token"
	"io/fs"
	"log"
	"os"
	"path/filepath"
	"strings"

	"gin-api-server/core_library/global"

	"github.com/duke-git/lancet/v2/fileutil"
	"github.com/gin-gonic/gin"
)

func ScanNoAuthControllerToClassMap(g *gin.Engine) {

	// 判断文件时候存在，不存在则解析。

	cpPath := global.RootPath + "/app/server"
	if !fileutil.IsExist(cpPath) {
		// 存在就直接读取， 写入
		log.Println("已编译 直接读取 -> NoNeedAuthRoutePath")
		f, err := os.ReadFile(global.RootPath + "/runtime/NoNeedAuthRoutePath.json")
		if err != nil {
			panic("读取文件(NoNeedAuthRoutePath)失败")
		}
		err = json.Unmarshal(f, &global.NONEEDAUTHMETHOD)
		if err != nil {
			log.Println(err.Error())
			panic("解析文件(NoNeedAuthRoutePath)失败")
		}
		return
	}

	var NoAuthControllerMethodMap = []string{}

	fset := token.NewFileSet()
	for _, info := range g.Routes() {
		if strings.Contains(info.Handler, "/app/server") {
			// url := info.Path
			handlers := strings.Split(info.Handler, "/")[1:]

			funcName := strings.Split(handlers[len(handlers)-1], ".")[1]
			handlers[len(handlers)-1] = strings.Split(handlers[len(handlers)-1], ".")[0]
			funcPath := strings.Join(handlers, "/") // 包目录
			// 获取包下面的文件
			err := filepath.WalkDir(funcPath, func(path string, d fs.DirEntry, err error) error {
				if strings.Contains(path, ".go") {
					funcFileContentByByte, err := os.ReadFile(path)
					if err != nil {
						return err
					}
					funcFileContent := string(funcFileContentByByte)
					f, err := parser.ParseFile(fset, path, funcFileContent, parser.ParseComments)
					if err != nil {
						return err
					}
					cmap := ast.NewCommentMap(fset, f, f.Comments)
					for node := range cmap {
						spec, ok := node.(*ast.FuncDecl)
						if ok {
							commentText := strings.ToLower(strings.TrimSpace(spec.Doc.Text()))

							if strings.Contains(commentText, "@noauth") {
								// 说明不需要鉴权
								if strings.EqualFold(spec.Name.Name, funcName) {
									NoAuthControllerMethodMap = append(NoAuthControllerMethodMap, info.Path)
									break
								}
							}

						}
					}
				}
				return nil
			})
			if err != nil {
				panic(err)
			}

			// 把文件写入到文件中
			marshal, err := json.Marshal(NoAuthControllerMethodMap)
			if err != nil {
				panic(err)
			}

			err = os.WriteFile(global.RootPath+"/runtime/NoNeedAuthRoutePath.json", marshal, 0777)
			if err != nil {
				panic(err)
			}

			global.NONEEDAUTHMETHOD = NoAuthControllerMethodMap

		}
	}

}
